package com.ruoyi.system.service.impl;

import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.billiards.common.EightBallWinTypeEnum;
import com.ruoyi.system.billiards.common.GameStatusEnum;
import com.ruoyi.system.billiards.common.GameTypeEnum;
import com.ruoyi.system.billiards.domian.request.EightBallScoreReq;
import com.ruoyi.system.billiards.domian.response.EightBallGameInfo;
import com.ruoyi.system.billiards.domian.response.GameInfo;
import com.ruoyi.system.domain.BilliardsGameEightBallMember;
import com.ruoyi.system.domain.BilliardsGameEightBallRecord;
import com.ruoyi.system.domain.BilliardsMember;
import com.ruoyi.system.domain.vo.BilliardsGameEightBallMemberVo;
import com.ruoyi.system.domain.vo.BilliardsGameVo;
import com.ruoyi.system.mapper.BilliardsGameEightBallMemberMapper;
import com.ruoyi.system.mapper.BilliardsGameEightBallRecordMapper;
import com.ruoyi.system.mapper.BilliardsMemberMapper;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.BilliardsGameMapper;
import com.ruoyi.system.domain.BilliardsGame;
import com.ruoyi.system.service.IBilliardsGameService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 比赛记录Service业务层处理
 *
 * @author ruoyi
 * @date 2024-12-11
 */
@Service
@RequiredArgsConstructor
public class BilliardsGameServiceImpl implements IBilliardsGameService {

    private final BilliardsGameMapper billiardsGameMapper;

    private final BilliardsGameEightBallMemberMapper billiardsGameEightBallMemberMapper;

    private final BilliardsGameEightBallRecordMapper billiardsGameEightBallRecordMapper;

    private final BilliardsMemberMapper billiardsMemberMapper;

    /**
     * 查询比赛记录
     *
     * @param gameId 比赛记录主键
     * @return 比赛记录
     */
    @Override
    public BilliardsGame selectBilliardsGameByGameId(Long gameId) {
        return billiardsGameMapper.selectBilliardsGameByGameId(gameId);
    }

    /**
     * 查询比赛记录列表
     *
     * @param billiardsGame 比赛记录
     * @return 比赛记录
     */
    @Override
    public List<BilliardsGame> selectBilliardsGameList(BilliardsGame billiardsGame) {
        return billiardsGameMapper.selectBilliardsGameList(billiardsGame);
    }

    /**
     * 新增比赛记录
     *
     * @param billiardsGame 比赛记录
     * @return 结果
     */
    @Override
    public BilliardsGame insertBilliardsGame(BilliardsGame billiardsGame) {
        BilliardsMember existMember = billiardsMemberMapper.selectBilliardsMemberByMemberId(Long.valueOf(billiardsGame.getCreateBy()));
        if (existMember == null) {
            throw new IllegalArgumentException("参数错误");
        }

        if (billiardsGame.getGameTime() == null) {
            billiardsGame.setGameTime(DateUtils.getNowDate());
        }
        billiardsGame.setStatus(GameStatusEnum.WAIT.getCode());
        billiardsGame.setCreateTime(DateUtils.getNowDate());

        billiardsGameMapper.insertBilliardsGame(billiardsGame);
        //将创建比赛的用户添加到比赛用户表
        BilliardsGameEightBallMember billiardsMember = BilliardsGameEightBallMember.builder().gameId(billiardsGame.getGameId()).memberId(Long.valueOf(billiardsGame.getCreateBy()))
                //默认红方
                .tag("0").build();
        billiardsGameEightBallMemberMapper.insertBilliardsGameEightBallMember(billiardsMember);
        return billiardsGame;
    }


    /**
     * 修改比赛记录
     *
     * @param billiardsGame 比赛记录
     * @return 结果
     */
    @Override
    public int updateBilliardsGame(BilliardsGame billiardsGame) {
        billiardsGame.setUpdateTime(DateUtils.getNowDate());
        return billiardsGameMapper.updateBilliardsGame(billiardsGame);
    }

    /**
     * 批量删除比赛记录
     *
     * @param gameIds 需要删除的比赛记录主键
     * @return 结果
     */
    @Override
    public int deleteBilliardsGameByGameIds(Long[] gameIds) {
        return billiardsGameMapper.deleteBilliardsGameByGameIds(gameIds);
    }

    /**
     * 删除比赛记录信息
     *
     * @param gameId 比赛记录主键
     * @return 结果
     */
    @Override
    public int deleteBilliardsGameByGameId(Long gameId) {
        return billiardsGameMapper.deleteBilliardsGameByGameId(gameId);
    }

    @Override
    public BilliardsGame selectCurGame(Long memberId, String gameType) {
        if (GameTypeEnum.EIGHT_BALL.getType().equals(gameType)) {
            List<BilliardsGameEightBallMember> memberList = billiardsGameEightBallMemberMapper.findCurGame(memberId, gameType);
            if (CollectionUtils.isEmpty(memberList)) {
                return null;
            }
            BilliardsGameEightBallMember member1 = memberList.get(0);
            return billiardsGameMapper.selectBilliardsGameByGameId(member1.getGameId());
//            gameInfo.setGameId(gameType);
//            gameInfo.setGameTime(billiardsGame.getGameTime());
//            gameInfo.setStatus(billiardsGame.getStatus());
//            EightBallGameInfo eightBallGameInfo = new EightBallGameInfo();
//
//            if (member1.getTag().equals("0")) {
//                eightBallGameInfo.setRed(member1);
//                eightBallGameInfo.setBlue(member2);
//            } else {
//                eightBallGameInfo.setRed(member2);
//                eightBallGameInfo.setBlue(member1);
//            }
//            gameInfo.setEightBallGame(eightBallGameInfo);
        }
        return null;
    }

    @Override
    @Transactional
    public void joinGame(Long gameId, Long memberId) {
        BilliardsGame billiardsGame = billiardsGameMapper.selectBilliardsGameByGameId(gameId);
        if (!billiardsGame.getStatus().equals(GameStatusEnum.WAIT.getCode())) {
            throw new IllegalArgumentException("比赛已开始或已结束");
        }
        //查询当前用户是否存在未开始的比赛，有的话退出
        List<BilliardsGame> gameList = billiardsGameMapper.findMemberNotBeginGame(memberId);
        for (BilliardsGame game : gameList) {
            back(game.getGameId());
        }

        //用户添加到比赛用户表
        BilliardsGameEightBallMember billiardsMember = BilliardsGameEightBallMember.builder().gameId(billiardsGame.getGameId()).memberId(memberId)
                //蓝方
                .tag("1").build();
        billiardsGameEightBallMemberMapper.insertBilliardsGameEightBallMember(billiardsMember);
        //创建局次
        BilliardsGameEightBallRecord record = BilliardsGameEightBallRecord.builder()
                //第一局
                .num(1L).status("0")
                .gameId(billiardsGame.getGameId()).build();
        record.setCreateTime(DateUtils.getNowDate());
        billiardsGameEightBallRecordMapper.insertBilliardsGameEightBallRecord(record);

        //更新比赛状态
        billiardsGame.setStatus(GameStatusEnum.START.getCode());
        billiardsGameMapper.updateBilliardsGame(billiardsGame);
    }

    @Override
    public GameInfo gameDetail(Long gameId) {
        GameInfo gameInfo = new GameInfo();
        BilliardsGame game = billiardsGameMapper.selectBilliardsGameByGameId(gameId);
        gameInfo.setGameType(game.getGameType());
        gameInfo.setGameName(game.getGameName());
        gameInfo.setGameId(game.getGameId());
        gameInfo.setStatus(game.getStatus());
        gameInfo.setGameTime(game.getGameTime());
        gameInfo.setCreateBy(game.getCreateBy());
        //查询中式八球比赛明细
        if (GameTypeEnum.EIGHT_BALL.getType().equals(game.getGameType())) {
            EightBallGameInfo eightBallGameInfo = new EightBallGameInfo();
            List<BilliardsGameEightBallMemberVo> memberList = billiardsGameEightBallMemberMapper.findByGameId(gameId);
            if (game.getStatus().equals(GameStatusEnum.WAIT.getCode())) {
                eightBallGameInfo.setRed(memberList.get(0));
            } else {
                BilliardsGameEightBallMemberVo billiardsGameEightBallMemberVo = memberList.get(0);
                if (billiardsGameEightBallMemberVo.getTag().equals("0")) {
                    eightBallGameInfo.setRed(memberList.get(0));
                    eightBallGameInfo.setBlue(memberList.get(1));
                } else {
                    eightBallGameInfo.setRed(memberList.get(1));
                    eightBallGameInfo.setBlue(memberList.get(0));
                }
            }
            gameInfo.setEightBall(eightBallGameInfo);

        }
        return gameInfo;
    }

    @Override
    @Transactional
    public void score(EightBallScoreReq eightBallScoreReq) {
        List<BilliardsGameEightBallMemberVo> eightBallMember = billiardsGameEightBallMemberMapper.findByGameId(eightBallScoreReq.getGameId());
        //更新得分
        billiardsGameEightBallMemberMapper.updateScore(eightBallScoreReq.getGameId(), eightBallScoreReq.getTag(), eightBallScoreReq.getScoreMethod());
        //更新对局记录
        BilliardsGameEightBallRecord billiardsGameEightBallRecord = billiardsGameEightBallRecordMapper.findMaxByGamaId(eightBallScoreReq.getGameId());
        Date createTime = billiardsGameEightBallRecord.getCreateTime();
        Long now = System.currentTimeMillis();
        //用时
        Long time = (now - createTime.getTime()) / 1000;
        billiardsGameEightBallRecord.setTime(time);
        billiardsGameEightBallRecord.setScoreMethod(eightBallScoreReq.getScoreMethod());
        BilliardsGameEightBallMemberVo member1 = eightBallMember.get(0);
        BilliardsGameEightBallMemberVo member2 = eightBallMember.get(1);
        Long winMember = null;
        Long loseMember = null;
        if (eightBallScoreReq.getTag().equals(member1.getTag())) {
            winMember = member1.getMemberId();
            loseMember = member2.getMemberId();
        } else {
            winMember = member2.getMemberId();
            loseMember = member1.getMemberId();
        }
        billiardsGameEightBallRecord.setWinMember(winMember);
        billiardsGameEightBallRecord.setLoseMember(loseMember);
        billiardsGameEightBallRecord.setStatus("1");
        billiardsGameEightBallRecordMapper.updateBilliardsGameEightBallRecord(billiardsGameEightBallRecord);
        //增加新的对局记录
        Long nextNum = billiardsGameEightBallRecord.getNum() + 1;
        BilliardsGameEightBallRecord newRecord = new BilliardsGameEightBallRecord();
        newRecord.setNum(nextNum);
        newRecord.setGameId(eightBallScoreReq.getGameId());
        newRecord.setCreateTime(DateUtils.getNowDate());
        newRecord.setStatus("0");
        billiardsGameEightBallRecordMapper.insertBilliardsGameEightBallRecord(newRecord);
    }

    @Override
    @Transactional
    public void end(Long gameId) {
        String status = "2";
        BilliardsGame billiardsGame = billiardsGameMapper.selectBilliardsGameByGameId(gameId);
        billiardsGame.setStatus("2");
        List<BilliardsGameEightBallMemberVo> memberVos = billiardsGameEightBallMemberMapper.findByGameId(gameId);
        if (memberVos.size() > 1) {
            BilliardsGameEightBallMemberVo member1 = memberVos.get(0);
            BilliardsGameEightBallMemberVo member2 = memberVos.get(1);
            if (member1.getScore().equals(member2.getScore())) {
                billiardsGame.setWinMember(0L);
                billiardsGame.setScore(member1.getScore() + ":" + member2.getScore());
            } else if (member1.getScore() > member2.getScore()) {
                billiardsGame.setWinMember(member1.getMemberId());
                billiardsGame.setLoseMember(member2.getMemberId());
                billiardsGame.setScore(member1.getScore() + ":" + member2.getScore());
            } else {
                billiardsGame.setWinMember(member2.getMemberId());
                billiardsGame.setLoseMember(member1.getMemberId());
                billiardsGame.setScore(member2.getScore() + ":" + member1.getScore());
            }
            billiardsGameMapper.updateBilliardsGame(billiardsGame);
        }

        billiardsGameEightBallRecordMapper.deleteNoCompleteRecord(gameId);

    }

    @Override
    public List<BilliardsGameVo> findByStatus(String status) {
        return billiardsGameMapper.findByStatus(status);
    }

    //退出对局
    @Override
    @Transactional
    public void back(Long gameId) {
        billiardsGameMapper.deleteBilliardsGameByGameId(gameId);
        billiardsGameEightBallMemberMapper.deleteByGameId(gameId);
    }

    @Override
    public List<BilliardsGameVo> myGames(Long memberId) {
        return billiardsGameMapper.myGames(memberId);
    }

}

